﻿
using System.Collections.Generic;
using UnityEngine;

public enum TerrainType
{
    /// <summary>
    /// 草地
    /// </summary>
    GrassLand,
    /// <summary>
    /// 石地
    /// </summary>
    RockField,
    /// <summary>
    /// 混合石场
    /// </summary>
    MixRockField,
    /// <summary>
    /// 高级混合石场
    /// </summary>
    AdvancedRockField,

    /// <summary>
    /// 温带平原
    /// </summary>
    WarmPlain,
    /// <summary>
    /// 温带稀疏林
    /// </summary>
    WarmLooseWood,
    /// <summary>
    /// 温带密林
    /// </summary>
    WarmMidWood,
    /// <summary>
    /// 温带竹林
    /// </summary>
    WarmBamboo,

    /// <summary>
    /// 热带平原
    /// </summary>
    TropicalPlain,
    /// <summary>
    /// 热带稀疏林
    /// </summary>
    TropicalLooseWood,
    /// <summary>
    /// 热带密林
    /// </summary>
    TropicalMidWood,

    /// <summary>
    /// 寒带平原，冰原
    /// </summary>
    ColdPlain,
    /// <summary>
    /// 寒带稀疏林
    /// </summary>
    ColdLooseWood,
    /// <summary>
    /// 寒带密林
    /// </summary>
    ColdMidWood,

    /// <summary>
    /// 炎热凤凰林
    /// </summary>
    DelonixRegia,

    /// <summary>
    /// 雪地
    /// </summary>
    SnowField,

    /// <summary>
    /// 毒雾沼泽
    /// </summary>
    Marsh,

    /// <summary>
    /// 腐烂黑森林
    /// </summary>
    DecayBlack,

    /// <summary>
    /// 桃林
    /// </summary>
    PeachWood,
}

public static class TerrainConst
{

    public static bool IsWarmTerrain(TerrainType terrain)
    {
        return terrain == TerrainType.WarmBamboo || terrain == TerrainType.WarmPlain ||
            terrain == TerrainType.WarmLooseWood || terrain == TerrainType.WarmMidWood ||
            terrain == TerrainType.DelonixRegia || terrain == TerrainType.PeachWood ||
            terrain == TerrainType.Marsh || terrain == TerrainType.RockField ||
            terrain == TerrainType.MixRockField;
    }

    public static bool IsColdTerrain(TerrainType terrain)
    {
        return terrain == TerrainType.ColdPlain || terrain == TerrainType.ColdLooseWood ||
            terrain == TerrainType.ColdMidWood || terrain == TerrainType.AdvancedRockField ||
            terrain == TerrainType.SnowField;
    }

    public static Color HexToColor(string hex)
    {
        if (string.IsNullOrEmpty(hex))
        {
            return new Color();
        }
        int colorInt = int.Parse(hex, System.Globalization.NumberStyles.AllowHexSpecifier);
        return IntToColor(colorInt);
        //hex = hex.ToLower();
        //byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
        //byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
        //byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
        //return new Color32(r, g, b, 255);
    }


    public static Color IntToColor(int colorInt)
    {
        float basenum = 255f;

        int b = 0xFF & colorInt;
        int g = 0xFF00 & colorInt;
        int r = 0xFF0000 & colorInt;
        g >>= 8;
        r >>= 16;
        return new Color(r / basenum, g / basenum, b / basenum, 1);
    }

    public static Dictionary<TerrainType, Color> TerrainColors = new Dictionary<TerrainType, Color>
        {
            { TerrainType.GrassLand, HexToColor("c2ffb2") },//HexToColor("6eaa73") },
            { TerrainType.RockField, HexToColor("e3e4e5") },
            { TerrainType.MixRockField, HexToColor("aec1cb") },
            { TerrainType.AdvancedRockField, HexToColor("889eab") },

            { TerrainType.WarmPlain, HexToColor("d5ffa4") },
            { TerrainType.WarmLooseWood, HexToColor("c5f38e") },// HexToColor("70a770") },
            { TerrainType.WarmMidWood, HexToColor("b7ee76") },// HexToColor("70a77e") },
            { TerrainType.WarmBamboo, HexToColor("85f785") },//HexToColor("6eaa73") },

            { TerrainType.TropicalPlain, HexToColor("9dffd7") },
            { TerrainType.TropicalLooseWood, HexToColor("7effca") },// HexToColor("337755") },
            { TerrainType.TropicalMidWood, HexToColor("6fedb6") },// HexToColor("8fa770") },

            { TerrainType.ColdPlain, HexToColor("a2f7ff") },
            { TerrainType.ColdLooseWood, HexToColor("a2e8ff") },//HexToColor("70a770") },
            { TerrainType.ColdMidWood, HexToColor("a0daff") },//HexToColor("8fa770") },
            { TerrainType.DelonixRegia, HexToColor("ff9999") },

            { TerrainType.SnowField, HexToColor("f8fcff") },
            { TerrainType.Marsh, HexToColor("c8c8f0") },
            //{ TerrainType.Waterland, HexToColor("62dafd") },

            //{ TerrainType.BareLand, HexToColor("a59992") },

            { TerrainType.DecayBlack, new Color(0.1f,0.1f,0.1f) /*HexToColor("5E5E5E")*/ },

            { TerrainType.PeachWood, HexToColor("fec3e1") },

        };

    public static Color RiverColor = HexToColor("16d9ea");// new Color32(22, 217, 234, 255);
    public static Color RiverBorderColor = HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color GrassColor = new Color32(56, 161, 92, 255);// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color GrassColorLiner = ((Color)new Color32(92, 196, 119, 255)).linear;// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color RedGrassColorLiner = ((Color)new Color32(196, 94, 93, 255)).linear;// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color ColdGrassColorLiner = ((Color)new Color32(99, 182, 217, 255)).linear;// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color RockGrassColorLiner = ((Color)new Color32(108, 145, 121, 255)).linear;// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color PeachGrassColorLiner = HexToColor("d49cb5").linear;// HexToColor("72e0ea");// new Color32(22, 217, 234, 255);
    public static Color AdvancedRockGrassColorLiner = HexToColor("516B5A").linear;
    public static Color BareLandColor = HexToColor("a59992");
    public static Color BareLandGroundColor = HexToColor("a59992").linear;
    public static Color WaterLandGroundColor = HexToColor("c4dedc").linear;


    public static Dictionary<TerrainType, Color> TerrainGroundColors = new Dictionary<TerrainType, Color>
        {
            { TerrainType.GrassLand, HexToColor("8CAA74").linear },//HexToColor("6eaa73") },
            { TerrainType.RockField, HexToColor("a59992").linear },
            { TerrainType.MixRockField, HexToColor("928781").linear },
            { TerrainType.AdvancedRockField, HexToColor("7a6355").linear },

            { TerrainType.WarmPlain, HexToColor("a79870").linear },
            { TerrainType.WarmLooseWood, HexToColor("A59F83").linear },// HexToColor("70a770") },
            { TerrainType.WarmMidWood, HexToColor("A59F83").linear },// HexToColor("70a77e") },
            { TerrainType.WarmBamboo, HexToColor("89AA7E").linear },//HexToColor("6eaa73") },

            { TerrainType.TropicalPlain, HexToColor("a79870").linear },
            { TerrainType.TropicalLooseWood, HexToColor("A59883").linear },// HexToColor("337755") },
            { TerrainType.TropicalMidWood, HexToColor("A59883").linear },// HexToColor("8fa770") },

            //{ TerrainType.ColdPlain, HexToColor("a79870") },
            { TerrainType.ColdPlain, HexToColor("7F94A5").linear },
            { TerrainType.ColdLooseWood, HexToColor("7F94A5").linear },
            { TerrainType.ColdMidWood, HexToColor("7F94A5").linear },
            { TerrainType.DelonixRegia, HexToColor("a77c70").linear },

            { TerrainType.SnowField, HexToColor("a8f0f0").linear },
            { TerrainType.Marsh, HexToColor("87628b").linear },
            //{ TerrainType.Waterland, HexToColor("6393Bc") },
            //{ TerrainType.BareLand, HexToColor("a59992") },

            { TerrainType.DecayBlack, new Color(0.1f,0.1f,0.1f) /*HexToColor("5E5E5E")*/ },

            { TerrainType.PeachWood, HexToColor("d48bac").linear },

        };

    public static Dictionary<TerrainType, string> TerrainChinese = new Dictionary<TerrainType, string>
        {
            { TerrainType.GrassLand, "草地" },
            { TerrainType.RockField, "石地" },
            { TerrainType.MixRockField, "混合石场" },
            { TerrainType.AdvancedRockField, "高级混合石场" },

            { TerrainType.WarmPlain, "温带平原" },
            { TerrainType.WarmLooseWood, "温带稀疏林" },
            { TerrainType.WarmMidWood, "温带密林" },
            { TerrainType.WarmBamboo, "温带竹林" },

            { TerrainType.TropicalPlain, "热带平原" },
            { TerrainType.TropicalLooseWood, "热带稀疏林" },
            { TerrainType.TropicalMidWood, "热带密林" },

            { TerrainType.ColdPlain, "寒带平原，冰原" },
            { TerrainType.ColdLooseWood, "寒带稀疏林" },
            { TerrainType.ColdMidWood, "寒带密林" },
            { TerrainType.DelonixRegia, "炽热凤凰林" },

            { TerrainType.SnowField, "雪地" },
            { TerrainType.Marsh, "沼泽" },
            //{ TerrainType.Waterland, "水地" },

            { TerrainType.DecayBlack, "腐烂黑森林" },

            { TerrainType.PeachWood, "桃林" },

            //{ TerrainType.BareLand, "裸土" },
        };

    public static Dictionary<TerrainType, float> TerrainGrassRate = new Dictionary<TerrainType, float>
        {
            { TerrainType.GrassLand, 0.8f },
            { TerrainType.RockField, 0.2f },
            { TerrainType.MixRockField, 0.1f },
            { TerrainType.AdvancedRockField, 0.02f },

            { TerrainType.WarmPlain, 0.5f },
            { TerrainType.WarmLooseWood, 0.5f },
            { TerrainType.WarmMidWood, 0.65f },
            { TerrainType.WarmBamboo, 0.6f },

            { TerrainType.TropicalPlain, 0.3f },
            { TerrainType.TropicalLooseWood, 0.6f },
            { TerrainType.TropicalMidWood, 0.7f },

            { TerrainType.ColdPlain, 0.3f },
            { TerrainType.ColdLooseWood, 0.6f },
            { TerrainType.ColdMidWood, 0.7f },
            { TerrainType.DelonixRegia, 0.5f },

            { TerrainType.SnowField, 0.025f },
            { TerrainType.Marsh, 0.2f },
            //{ TerrainType.Waterland, 0.2f },

            //{ TerrainType.BareLand, 0 },

            { TerrainType.DecayBlack, 0.5f },

            { TerrainType.PeachWood, 0.5f },
        };


    public static Dictionary<TerrainType, float> TemperatureOnTerrainDic = new Dictionary<TerrainType, float>()
    {
        /// 草地
        { TerrainType.GrassLand,26 },
        /// 石地
        { TerrainType.RockField,30 },
        /// 混合石场
        { TerrainType.MixRockField,40 },
        /// 高级混合石场
        { TerrainType.AdvancedRockField,-5f },
        /// 温带平原
        { TerrainType.WarmPlain,32 },
        /// 温带稀疏林
        { TerrainType.WarmLooseWood,28 },
        /// 温带密林
        { TerrainType.WarmMidWood,26 },
        /// 温带竹林
        { TerrainType.WarmBamboo,20 },

        /// 热带平原
        { TerrainType.TropicalPlain,38 },
        /// 热带稀疏林
        { TerrainType.TropicalLooseWood,34 },
        /// 热带密林
        { TerrainType.TropicalMidWood,30 },

        /// 寒带平原，冰原
        { TerrainType.ColdPlain,8 },
        /// 寒带稀疏林
        { TerrainType.ColdLooseWood,5 },
        /// 寒带密林
        { TerrainType.ColdMidWood,0 },

        /// 雪地
        { TerrainType.SnowField,-25 },

        /// 炽热凤凰林
        { TerrainType.DelonixRegia,50 },
        /// 沼泽
        { TerrainType.Marsh,20 },
        //腐烂黑森林
        { TerrainType.DecayBlack,10 },
        //桃树林
        { TerrainType.PeachWood,30 },
    };

    public static Dictionary<TerrainType, string> TreasureOnTerrainDic = new Dictionary<TerrainType, string>()
    {
        /// 草地
        { TerrainType.GrassLand, ""/*"centipede*1/10"*/ },
        /// 石地
        { TerrainType.RockField,"[clay*1/0.2+fire_clay*1/0.1]" },
        /// 混合石场
        { TerrainType.MixRockField,"[clay*1/0.2+fire_clay*1/0.1+china_clay*1/0.1]" },
        /// 高级混合石场
        { TerrainType.AdvancedRockField,"[clay*1/0.2+fire_clay*1/0.1+china_clay*1/0.2]" },
        /// 温带平原
        { TerrainType.WarmPlain,"[clay*1/0.2]" },
        /// 温带稀疏林
        { TerrainType.WarmLooseWood,"[clay*1/0.15]"/*"earthworm*1/10"*/ },
        /// 温带密林
        { TerrainType.WarmMidWood,"[clay*1/0.15]"/*"earthworm*1/15"*/ },
        /// 温带竹林
        { TerrainType.WarmBamboo,"" },
        /// 热带平原
        { TerrainType.TropicalPlain,"[clay*1/0.2+fire_clay*1/0.15]" },
        /// 热带稀疏林
        { TerrainType.TropicalLooseWood,"[clay*1/0.2+fire_clay*1/0.15]" },
        /// 热带密林
        { TerrainType.TropicalMidWood,"[clay*1/0.2+fire_clay*1/0.15]" },
        /// 寒带平原，冰原
        { TerrainType.ColdPlain,"[clay*1/0.1+china_clay*1/0.2]" },
        /// 寒带稀疏林
        { TerrainType.ColdLooseWood,"[clay*1/0.1+china_clay*1/0.2]" },
        /// 寒带密林
        { TerrainType.ColdMidWood,"[clay*1/0.1+china_clay*1/0.2]" },
        /// 寒带凤凰林
        { TerrainType.DelonixRegia,"[fire_clay*1/0.25]" },
        /// 雪地
        { TerrainType.SnowField,"" },
        /// 沼泽
        { TerrainType.Marsh,"" },
        /// 水地
        //{ TerrainType.Waterland,"" },
        /// 悬崖
        //{ TerrainType.BareLand,"" },
        //腐烂黑森林
        { TerrainType.DecayBlack,"" },
    };

}



public enum TerrainLandStatus
{
    /// <summary>
    /// 原本地形
    /// </summary>
    Origin,
    /// <summary>
    /// 长草
    /// </summary>
    Grass,
    /// <summary>
    /// 裸露土地，不可长草与放置单位，但是有原来地形颜色
    /// </summary>
    Bare,
    /// <summary>
    /// 完全裸露土地，不可长草与放置单位，没有原来地形
    /// </summary>
    TotallyBare,
    /// <summary>
    /// 挖掘过的
    /// </summary>
    Hoed,
    /// <summary>
    /// 河道
    /// </summary>
    RiverWay,
}

public struct GameLogicAreaData
{
    //从0开始
    public ushort id;
    public ushort midAreaId;
    public ushort[] areaIds;
    public Vector2Int altarGrid;
    public Vector2Int chaosfishGrid;

    public void ReadBinary(System.IO.BinaryReader br)
    {
        id = br.ReadUInt16();
        midAreaId = br.ReadUInt16();
        chaosfishGrid = new Vector2Int(br.ReadInt32(), br.ReadInt32());
        altarGrid = new Vector2Int(br.ReadInt32(), br.ReadInt32());

        var ncnt = br.ReadByte();
        areaIds = new ushort[ncnt];
        for (int i = 0; i < ncnt; i++)
        {
            areaIds[i] = br.ReadUInt16();
        }
    }

    public void WriteBinary(System.IO.BinaryWriter bw)
    {
        bw.Write(id);
        bw.Write(midAreaId);
        bw.Write(chaosfishGrid.x);
        bw.Write(chaosfishGrid.y);
        bw.Write(altarGrid.x);
        bw.Write(altarGrid.y);

        bw.Write((byte)areaIds.Length);
        for (int i = 0; i < areaIds.Length; i++)
            bw.Write(areaIds[i]);
    }

}

public struct TerrainAreaData
{
    //从0开始
    public ushort id;
    public ushort gameLogicAreaId;
    public TerrainType terrainType;
    public float fog;
    //默认为0，做动画时从1到0变化
    public float fogTransi;
    public ushort[] neighborIds;
    public Vector2Int[] centerPoints;

    public void ReadBinary(System.IO.BinaryReader br)
    {
        id = br.ReadUInt16();
        gameLogicAreaId = br.ReadUInt16();
        terrainType = (TerrainType)br.ReadByte();
        fog = br.ReadSingle();

        var ncnt = br.ReadByte();
        neighborIds = new ushort[ncnt];
        for (int i = 0; i < ncnt; i++)
            neighborIds[i] = br.ReadUInt16();

        var cpc = br.ReadByte();
        centerPoints = new Vector2Int[cpc];
        for (int i = 0; i < cpc; i++)
        {
            centerPoints[i] = new Vector2Int(br.ReadInt32(), br.ReadInt32());
        }
    }

    public void WriteBinary(System.IO.BinaryWriter bw)
    {
        bw.Write(id);
        bw.Write(gameLogicAreaId);
        bw.Write((byte)terrainType);
        bw.Write(fog);

        bw.Write((byte)neighborIds.Length);
        for (int i = 0; i < neighborIds.Length; i++)
            bw.Write(neighborIds[i]);

        bw.Write((byte)centerPoints.Length);
        for (int i = 0; i < centerPoints.Length; i++)
        {
            ref var cp = ref centerPoints[i];
            bw.Write(cp.x);
            bw.Write(cp.y);
        }
    }

}

public struct TerrainGridData
{

    public TerrainType terrainType;

    public TerrainLandStatus landStatus;

    public float groundHeight;

    public byte marginIdx;

    public byte terrainByte;

    public ushort areaId;

    public bool notAllowCreature
    {
        get
        {
            return (byte)(terrainByte & 1) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | 1) : (byte)(terrainByte & ~1);
        }
    }

    public bool isPool
    {
        get
        {
            return (byte)(terrainByte & (1 << 1)) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | (1 << 1)) : (byte)(terrainByte & ~(1 << 1));
        }
    }

    public bool isPoolBorder
    {
        get
        {
            return (byte)(terrainByte & (1 << 2)) > 0;
        }
        set
        {
            if (value) isPool = true;
            terrainByte = value ? (byte)(terrainByte | (1 << 2)) : (byte)(terrainByte & ~(1 << 2));
        }
    }

    public bool isTerrainBorder
    {
        get
        {
            return (byte)(terrainByte & (1 << 3)) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | (1 << 3)) : (byte)(terrainByte & ~(1 << 3));
        }
    }

    /// <summary>
    /// 是否禁止建筑
    /// </summary>
    public bool forbidBuilding
    {
        get
        {
            return (byte)(terrainByte & (1 << 4)) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | (1 << 4)) : (byte)(terrainByte & ~(1 << 4));
        }
    }

    /// <summary>
    /// 是否禁止种植
    /// </summary>
    public bool forbidPlanting
    {
        get
        {
            return (byte)(terrainByte & (1 << 5)) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | (1 << 5)) : (byte)(terrainByte & ~(1 << 5));
        }
    }

    /// <summary>
    ///  是否无雾
    /// </summary>
    public bool isFogVoid
    {
        get
        {
            return (byte)(terrainByte & (1 << 6)) > 0;
        }
        set
        {
            terrainByte = value ? (byte)(terrainByte | (1 << 6)) : (byte)(terrainByte & ~(1 << 6));
        }
    }

    public bool isPoolWater
    {
        get
        {
            return isPool && !isPoolBorder;
        }
        set
        {
            if (value)
            {
                isPool = true;
                isPoolBorder = false;
            }
            else
            {
                isPoolBorder = isPool;
            }
        }
    }

    public void ReadBinary(System.IO.BinaryReader br)
    {
        terrainType = (TerrainType)br.ReadByte();
        groundHeight = br.ReadSingle();
        landStatus = (TerrainLandStatus)br.ReadByte();
        terrainByte = br.ReadByte();
        marginIdx = br.ReadByte();
        areaId = br.ReadUInt16();
    }

    public void WriteBinary(System.IO.BinaryWriter bw)
    {
        bw.Write((byte)terrainType);
        bw.Write(groundHeight);
        bw.Write((byte)landStatus);
        bw.Write(terrainByte);
        bw.Write(marginIdx);
        bw.Write(areaId);
    }

}


